package cn.qdhlm.collectservice.core.component.analyse;

import cn.qdhlm.collectservice.common.Constant;
import cn.qdhlm.collectservice.common.util.CodeUtil;
import cn.qdhlm.collectservice.common.util.ComUtil;
import cn.qdhlm.collectservice.common.util.JsonUtil;
import cn.qdhlm.collectservice.core.component.Checker;
import cn.qdhlm.collectservice.model.rocketmq.TerminalData;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @Name: AnyAfn0c
 * @Description: 控制（AFN=0CH）
 * @Author: jiangcs
 */
@Log4j2
@Component
public class AnyAfna0 {
    public boolean execute(int fn, int sn, ByteBuf byteBuf, TerminalData terminalData) {
        // 执行结果
        boolean executeFlag = false;

        switch (fn) {
            // F1：WAC350阀抄水表充值水量实时参数
            case 1:
                // 数据包长度
                int packageLength = byteBuf.readShortLE();
                if (packageLength <= 0) {
                    log.warn("execute: packageLength <= 0");
                } else {
                    // 2: 1-CS；1-16
                    int actualPackageLength = byteBuf.readableBytes() - 2;
                    if (packageLength != actualPackageLength) {
                        log.error("execute: packageLength[{}] not equal actualPackageLength[{}]", packageLength, actualPackageLength);
                    } else {
                        // 截取 实时参数数据包
                        ByteBuf byteBufData = byteBuf.copy(byteBuf.readerIndex(), packageLength);

                        log.info("execute: packageLength[{}], byteBufData[{}]", packageLength, ByteBufUtil.hexDump(byteBufData));

                        boolean checkFlag = Checker.checkTransparent(byteBufData);
                        if (checkFlag) {
                            // 跳过1个字节：起始字符
                            byteBufData.skipBytes(1);
                            // 仪表类型：46-智能调节阀
                            String deviceType = CodeUtil.byteToHexString(byteBufData.readByte());
                            // 跳过 7个字节：地址域
                            byteBufData.skipBytes(7);
                            // 控制码
                            String controlCode = CodeUtil.byteToHexString(byteBufData.readByte());
                            // 数据长度
                            int dataLength = byteBufData.readByte();

                            log.info("execute: deviceType[{}], controlCode[{}], dataLength[{}]", deviceType, controlCode, dataLength);

                            // 处理数据
                            Map<String, Object> resultMap = processTransparentData(byteBufData,terminalData.getTerminalId() );
                            if (resultMap != null) {
                                log.info("execute sn[{}] result: {}", sn, JsonUtil.safeJsonStr(resultMap));

                                executeFlag = true;
                            }
                        }
                    }
                }
                break;
            default:
                log.error("execute: fn[{}] match fail", fn);
        }

        return executeFlag;
    }

    private Map<String, Object> processTransparentData(ByteBuf byteBuf, Integer terminalId) {
        Map<String, Object> resultMap;

        // 数据标识
        String dataSymbol = CodeUtil.shortToHexString(byteBuf.readShort());
        // 序列号
        int sn = byteBuf.readUnsignedByte();

        log.info("processData: terminalId[{}], dataSymbol[{}], sn[{}]", terminalId, dataSymbol, sn);

        String cleanCycleLow, cleanCycleHigh;

        switch (dataSymbol) {
            // 实时参数-WAC350（A3/01）
            case "a301":
                resultMap = new HashMap<>(9);
                // 阀门清洗间隔720小时，BCD格式
                cleanCycleLow = CodeUtil.byteToHexString(byteBuf.readByte());
                cleanCycleHigh = CodeUtil.byteToHexString(byteBuf.readByte());
                resultMap.put("cleanCycle", ComUtil.safeInt(cleanCycleHigh + cleanCycleLow));
                // 住户类型，00：NULL，01：民用，02：商用。BIN格式
                int householdType = byteBuf.readByte();
                resultMap.put("householdType", householdType);
                // 扣费类型，00：NULL，01：水量，02：金额。BIN格式
                int deductionType = byteBuf.readByte();
                resultMap.put("deductionType", deductionType);
                // 计费方式，00：NULL。BIN格式
                int chargeFactory = byteBuf.readByte();
                resultMap.put("chargeFactory", chargeFactory);
                // 购买序列，BIN格式。
                int buyNum = byteBuf.readShortLE();
                resultMap.put("buyNum", buyNum);
                // 下级地址，00000000000012，BCD格式
                StringBuilder sbSubMacAddr = new StringBuilder();
                for (int i = 0; i < Constant.BYTE_LENGTH_MAC_ADDR + Constant.BYTE_LENGTH_FACTORY; i++) {
                    sbSubMacAddr.append(CodeUtil.byteToHexString(byteBuf.readByte()));
                }
                resultMap.put("subMacAddr", sbSubMacAddr);
                // 下级协议ID。BIN格式
                int subProtocolId = byteBuf.readShortLE();
                resultMap.put("subProtocolId", subProtocolId);
                // 采集周期，单位分钟。BIN格式。
                int collectCycle = byteBuf.readShortLE();
                resultMap.put("collectCycle", collectCycle);
                break;
            default:
                resultMap = null;

                log.error("processData: dataSymbol[{}] match fail", dataSymbol);
        }

        return resultMap;
    }
}
